package com.fzy.common.file;

import org.apache.commons.lang3.StringUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.zip.ZipInputStream;

/**
 * 解压，压缩文件工具
 */
public class ZipFileUtil {

    private ZipFileUtil() {
    }

    private static Logger logger = LoggerFactory.getLogger(ZipFileUtil.class);

    /**
     * 解压zip文件
     *
     * @param zipFileName     ：zip文件全路径
     * @param outputDirectory ：解压到得路径 如果为空 则解压到zipFileName文件的当前目录下
     * @return list 文件解压缩后的文件列表绝对路径
     */
    @SuppressWarnings("unchecked")
    public static void unZipFile(String zipFileName, String outputDirectory) {
        ArrayList list = new ArrayList();
        if (StringUtils.isEmpty(zipFileName)) {
            return;
        }
        if (StringUtils.isEmpty(outputDirectory)) {
            outputDirectory = zipFileName.substring(0, zipFileName.replace('\\', '/').lastIndexOf("/"));
        }
        File file = new File(zipFileName);
        if (!file.exists()) {
            return;
        }
        outputDirectory = createDirectory(outputDirectory, "");
        FileOutputStream out = null;
        InputStream in = null;
        try {
            ZipFile zipFile = new ZipFile(zipFileName);
            Enumeration e = zipFile.getEntries();
            ZipEntry zipEntry = null;
            while (e.hasMoreElements()) {
                zipEntry = (ZipEntry) e.nextElement();
                if (zipEntry.isDirectory()) {
                    String name = zipEntry.getName();
                    name = name.substring(0, name.length() - 1);
                    File f = new File(outputDirectory + File.separator + name);
                    f.mkdir();
                } else {
                    String fileName = zipEntry.getName();
                    fileName = fileName.replace('\\', '/');
                    // 文件在多层目录下 这时需要创建目录如：d1/d2/1.txt
                    if (fileName.indexOf("/") != -1) {
                        createDirectory(outputDirectory, fileName.substring(0, fileName.lastIndexOf("/")));
                        fileName = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());
                    }

                    list.add(outputDirectory + File.separator + zipEntry.getName());
                    File f = new File(outputDirectory + File.separator + zipEntry.getName());

                    f.createNewFile();
                    in = zipFile.getInputStream(zipEntry);
                    out = new FileOutputStream(f);

                    byte[] by = new byte[1024];
                    int c;
                    while ((c = in.read(by)) != -1) {
                        out.write(by, 0, c);
                    }
                    out.close();
                    in.close();
                }
            }
        } catch (Exception ex) {
            logger.error("解压缩失败", ex);
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    // 创建目录
    private static String createDirectory(String directory, String subDirectory) {
        String dir[];
        File fl = new File(directory);
        try {
            if (subDirectory == "" && fl.exists() != true) {
                fl.mkdirs();
            } else if (!subDirectory.equals("")) {
                dir = subDirectory.replace("\\", "/").split("/");
                for (int i = 0; i < dir.length; i++) {
                    File subFile = new File(directory + File.separator + dir[i]);
                    if (!subFile.exists()) {
                        subFile.mkdir();
                    }
                    directory += File.separator + dir[i];
                }
            }
        } catch (Exception ex) {
            logger.error("创建路径失败", ex);

        }
        return directory;
    }

    /***
     * 不解压直接读取zip文件内指定文件的内容
     **/
    public static void readZipFile(String file) throws Exception {
        ZipFile zf = new ZipFile(file);
        InputStream in = new BufferedInputStream(new FileInputStream(file));

        ZipInputStream zin = new ZipInputStream(in);
        ZipEntry ze;
        while ((ze = (ZipEntry) zin.getNextEntry()) != null) {
            if (ze.isDirectory()) {
            } else {
                System.err.println("file - " + ze.getName() + " : "
                        + ze.getSize() + " bytes");
                long size = ze.getSize();
                if (size > 0) {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(zf.getInputStream(ze)));
                    String line;
                    while ((line = br.readLine()) != null) {
                        System.out.println(line);
                    }
                    br.close();
                }
                System.out.println();
            }
        }
        zin.closeEntry();
    }

}

